/* 
 * BaseController.java      1.00    2008-01-11
 *
 * Copyright (c) 2010 leewan. All Rights Reserved.
 * 
 * This software is the confidential and proprietary information
 * of leewan.  You shall not disclose such Confidential Information
 * and shall use it only in accordance with the terms of the license agreement
 * you entered into with leewan.
 */
package doit.framework.controller;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

import doit.framework.facade.BaseFacade;
import doit.framework.util.Constants;
import doit.framework.util.AnnotationController;
import doit.framework.util.PageGenerator;
import doit.framework.util.RedirectUtil;
import doit.framework.util.SharedMethods;

/**
 * <pre>
 * system      : 공통
 * menu        : 공통
 * source      : BaseController.java
 * description : 공통 Controller 부모 클래스
 * </pre> 
 * @version
 * <pre> 
 * 1.0	2008-01-11  leewan  최초 작성
 * 1.1	
 * </pre>
 */

@SuppressWarnings("unchecked")

public abstract class BaseController extends MultiActionController implements BaseFacade {

	@Autowired
	private AnnotationController annotationController;
	
	private String init = null;
	private String pageList = null;
	private String list = null;
	private String view = null;
	private String insertForm = null;
	private String insert = null;
	private String updateForm = null;
	private String update = null;
	private String delete = null;
	private String deleteAll = null;
	private String initMethod = null;
	private String beanName = null;
	private String viewName = null;
	
	public String getInit() {
		return init;
	}
	public void setInit(String init) {
		this.init = init;
	}
	public String getPageList() {
		return pageList;
	}
	public void setPageList(String pageList) {
		this.pageList = pageList;
	}
	public String getList() {
		return list;
	}
	public void setList(String list) {
		this.list = list;
	}
	public String getView() {
		return view;
	}
	public void setView(String view) {
		this.view = view;
	}
	public String getInsertForm() {
		return insertForm;
	}
	public void setInsertForm(String insertForm) {
		this.insertForm = insertForm;
	}
	public String getInsert() {
		return insert;
	}
	public void setInsert(String insert) {
		this.insert = insert;
	}
	public String getUpdateForm() {
		return updateForm;
	}
	public void setUpdateForm(String updateForm) {
		this.updateForm = updateForm;
	}
	public String getUpdate() {
		return update;
	}
	public void setUpdate(String update) {
		this.update = update;
	}
	public String getDelete() {
		return delete;
	}
	public void setDelete(String delete) {
		this.delete = delete;
	}
	public String getDeleteAll() {
		return deleteAll;
	}
	public void setDeleteAll(String deleteAll) {
		this.deleteAll = deleteAll;
	}	
	public String getInitMethod() {
		return initMethod;
	}
	public void setInitMethod(String initMethod) {
		this.initMethod = initMethod;
	}
	public String getBeanName() {
		return beanName;
	}
	public void setBeanName(String beanName) {
		this.beanName = beanName;
	}
    public String getViewName() {
		return viewName;
	}
	public void setViewName(String viewName) {
		this.viewName = viewName;
	}
	
	protected ModelAndView init( HttpServletRequest request, HttpServletResponse response) throws Exception {
    	Map input = new HashMap();
        bind( request, input);
    	ModelAndView modelAndView = null;
    	Map model = new PageGenerator().generate( request, input, null);
		modelAndView = new ModelAndView(this.getInit(), model);
    	return modelAndView;
    }	
	
	@Override
	protected ModelAndView handleRequestInternal( HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		String requestMethodName = null;
		
		boolean isMethod = false;
		
		if (this.getMethodNameResolver().getHandlerMethodName(request) != null) {
			requestMethodName = this.getMethodNameResolver().getHandlerMethodName(request);
			if ((requestMethodName == null || requestMethodName.equals(Constants.VL_METHOD_INIT))  && this.getInitMethod() != null) {
				isMethod = SharedMethods.validateMethod(this.getClass(), this.getInitMethod());
			} else {
				isMethod = SharedMethods.validateMethod(this.getClass(), requestMethodName);
			}
		}
		
		String className = SharedMethods.getClassName( this.getClass());
		
		ModelAndView modelAndView = annotationController.annotation(request, response, className);
		modelAndView = annotationController.sessionChecker(request, response, className);
		
		if (modelAndView == null ) {
			if (requestMethodName.equals(Constants.VL_METHOD_INIT) || !isMethod) {
				if (this.getInitMethod() != null && isMethod) {
					modelAndView = this.invokeNamedMethod(this.getInitMethod(), request,  response);
				} else {
					modelAndView = init(request, response);
				}
			} else {
				modelAndView = super.handleRequestInternal( request, response);
			}
		} 
		if ( modelAndView.getViewName() != null && modelAndView.getViewName().indexOf(Constants.VL_REDIRECT) < 0) {
			// 메뉴 설정
			getMenu(modelAndView);
		} else {
			this.redirect(request, response, modelAndView.getModel(), modelAndView.getViewName().replaceAll(Constants.VL_REDIRECT, Constants.VL_EMPTY));
			modelAndView = null;
		}
		
		return modelAndView;
	}
	
	protected void redirect(HttpServletRequest request, HttpServletResponse response, Map model, String viewName) throws Exception
	{
		if (viewName != null)
			RedirectUtil.redirect(request, response, model, viewName);
		else
			response.sendRedirect(Constants.VL_REDIRECT_PREFIX);
	}	
	
	protected void getMenu(ModelAndView modelAndView) throws Exception {
	//	return modelAndView;
	}
	
	protected boolean validateMethod(HttpServletRequest request) throws Exception {
		boolean isMethod = false;
		if (this.getMethodNameResolver().getHandlerMethodName(request) != null) {
			Method[] methods = this.getClass().getMethods();
			String requestMethodName = this.getMethodNameResolver().getHandlerMethodName(request);
			for (Object method : methods) {
				if (((Method)method).getName().equals(requestMethodName)) {
					isMethod = true;
					break;
				}
			}
		}
		return isMethod;
	}
	
	protected void bind( HttpServletRequest request, Map input) throws Exception{
        
		SharedMethods.bind(request, input);
       	
       	String location = request.getRequestURI();
       	int getParamIdx = location.indexOf(Constants.VL_PARAMETER_START_PREFIX);
       	if (getParamIdx > 0) {
       		location = location.substring(0, getParamIdx);	
       	}
       	input.put(Constants.VL_LOCATION, request.getRequestURI());
       	
       	if ( this.getMethodNameResolver().getHandlerMethodName(request) == null || 
       		 this.getMethodNameResolver().getHandlerMethodName(request).equals(Constants.VL_EMPTY) || 
       		 !this.validateMethod(request)) {
       		input.put(Constants.PM_METHOD, Constants.VL_METHOD_INIT);
       	} else {
       		input.put(Constants.PM_METHOD, this.getMethodNameResolver().getHandlerMethodName(request));
       	}
	}
	
	protected void bind( HttpServletRequest request, Object domain) throws Exception{
		SharedMethods.bind(request, domain);
	}
	
	protected boolean bindCheckBox(HttpServletRequest request, Map input, String iterateName) throws Exception {
		boolean _ret = false;
		ArrayList aRchk = new ArrayList();
		String[] chk = request.getParameterValues( iterateName);
		if (chk != null && chk.length > 0) {
			for (int i = 0 ; i < chk.length ; i++) {
				aRchk.add(chk[i]);
			}
			input.put(iterateName, aRchk);
			_ret = true;
		}
		SharedMethods.bindUpdInfo( request, input);
		
		return _ret;
	}
	protected boolean bindCheckBox(HttpServletRequest request, Map input, String iterateName, String checkBoxName) throws Exception {
		boolean _ret = false;
		ArrayList aRchk = new ArrayList();
		String[] chk = request.getParameterValues( checkBoxName);
		if (chk != null && chk.length > 0) {
			for (int i = 0 ; i < chk.length ; i++) {
				aRchk.add(chk[i]);
			}
			input.put(iterateName, aRchk);
			_ret = true;
		}
		
		SharedMethods.bindUpdInfo( request, input);
		
		return _ret;
	}
}
